import re
import webbrowser
import string

from kivy.metrics import dp
from kivy.logger import Logger
from kivy.metrics import dp, sp
from kivy.uix.scrollview import ScrollView

from amgineirc.layout.labelLogLayout import LabelLogLayout


class LogView(ScrollView):
    """
    in this view the user sees messages from the internet.
    they appear hear as in a log dump.
    lines are printed from top to bottom.
    http and https urls are clickable and the url is opened in the browser.
    """
    _urlPattern = re.compile(r'(https?://\S+)')
    _notURLPattern = re.compile(r'((?<!//)www\.\S+)')
    _filter = None

    def __init__(self, **kargs):
        if 'maximum_log_count' in kargs:
            maximum_log_count = kargs['maximum_log_count']
            del(kargs['maximum_log_count'])
        else:
            maximum_log_count = 50
        ScrollView.__init__(self, **kargs)
        self._url_count = 0
        self._urls = {}
        # create logger layout
        self._layout = LabelLogLayout(self.w_handle_ref_on_press,
                                      0, # no min line height
                                      True, # scroll with new children
                                      size_hint=(1.0, None),
                                      spacing=dp(10),
                                      padding=dp(5),
                                      maximum_log_count=maximum_log_count)
        self.add_widget(self._layout)
        if LogView._filter is None:
            LogView._filter = list(string.punctuation)
            LogView._filter.remove('/')
            
    def _build_markup(self, text):
        """overridable method for adding new refs
        
        ex:
        def _build_markup(self, text):
            text = LogView._build_markup(self, text):
            view_more_button = self._build_more_button_markup()
            return text + ' ' + view_more_button
        """
        # fix the url 'http://www.thing.com/.' to 'http://www.thing.com/'   
        text = self._mark_up(LogView._urlPattern, text)
        # fix the url 'www.thing.com/.' to 'http://www.thing.com/'   
        text = self._mark_up(LogView._notURLPattern, text)
        return text
        
    def _mark_up(self, pattern, text):
        iterator = pattern.finditer(text)
        # store matches in reverse order
        matches = []
        for match in iterator:
            http = match.group(0)
            for i in range(len(http)-1, -1, -1):
                if http[i] not in LogView._filter:
                    fixed_url = http[:i+1]
                    matches.insert(0, [match.start(), fixed_url, fixed_url])
                    break
        # iterate replacing in string from end to start
        for m in matches:
            start, url, fixed_url = m
            ref = 'url' + str(self._url_count)
            clean_url = fixed_url.replace('&bl;','[').replace('&br;',']')
            end = start + len(url)
            self._urls[ref] = fixed_url
            self._url_count += 1
            replacement = '[color=#8eabbd][b][ref={0}]{1}[/ref][/b][/color]'.format(ref, clean_url)
            parts = []
            parts.append(text[:start])
            parts.append(replacement)
            parts.append(text[end:])
            text = ''.join(parts)
        return text

    # view model methods

    def vm_log(self, text):
        """Add text onto the end of the log.
        Returns true if text was added else false.
        """
        safe = text.replace('[', '&bl;').replace(']','&br;')
        mu = self._build_markup(safe)
        # add the text
        return self._layout.log(mu)

    def vm_set_state(self, **kargs):
        if 'connected' in kargs:
            # show connected
            pass

    # widget methods
    
    def w_handle_ref_on_press(self, label, ref):
        """overridable method
        ex:
        def w_handle_ref_on_press(self, label, ref):
            if ref[:8] == 'viewmore':
                self._open_more_popup(self.viewmore_texts[ref])
            else:
                LogView.w_handle_ref_on_press(self, label, ref)
        """
        if ref[:3] == 'url':
            webbrowser.open_new_tab(self._urls[ref])

    # private methods
